package com.meringer.beans;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.ejb.EJB;
import javax.ejb.Timer;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;

import com.meringer.beans.ejb.RacesEJB;
import com.meringer.beans.ejb.StatsEJB;
import com.meringer.beans.ejb.UserEJB;
import com.meringer.entities.Race;
import com.meringer.entities.RaceResult;
import com.meringer.entities.User;

/**
 * JSF bean for the chooseRace.xhtml page
 * @author K.Zlatanov
 */
@ManagedBean(name="raceBean")
@SessionScoped
public class RaceBean
{
	@EJB
	private RacesEJB racesEJB;
	
	@EJB
	private UserEJB userEJB;
	
	@EJB
	private StatsEJB statsEJB;

	private Long enteredRaceID;
	private Long previousRaceID;
	
	public RaceBean()
	{}
	
	public User getCurrentUser()
	{
		return userEJB.currentUser();
	}
	
	/**
	 * Called when user chooses a given race.
	 */
	public String enterRace(Long raceID)
	{
		racesEJB.enterRace(getCurrentUser(), raceID);
		enteredRaceID = raceID;
		
		// If the user had taken the last available slot on race then the race hasfinished
		if (checkIfEnteredRaceFinished()) {
			previousRaceID = enteredRaceID;
			enteredRaceID = null;
			return "raceResults?faces-redirect=true";
		}
		return null;
	}
	
	/**
	 * Check if race has already finished and writen to DB history
	 */
	private boolean checkIfEnteredRaceFinished()
	{
		if (enteredRaceID == null) 
			return false;
		
		// Presume that if it is not on the race list then it has finished
		List<Race> currentRacesList = getRaces();
		for (Race race : currentRacesList)
		{
			if (enteredRaceID.equals(race.getRaceID())) {
				return false;
			}
		}
		return true;
	}
	
	/**
	 * Listens to the poller on the page. Check if race has begun and finished
	 * and redirects to raceResults page if such is the case.
	 */
	public void poll()
	{
		if (checkIfEnteredRaceFinished())
		{
			try {
				// Check if race really happened or just expired cause there 
				// had been just a singles contestant
				if (racesEJB.isRaceInHistory(enteredRaceID)) {
					previousRaceID = enteredRaceID;
					enteredRaceID = null;
					FacesContext.getCurrentInstance().getExternalContext().redirect("raceResults.xhtml");
				}
				else {
					previousRaceID = null;
					enteredRaceID = null;
				}
			} 
			catch (IOException e) {
				e.printStackTrace();
				throw new RuntimeException(e);
			}
		}
	}
	
	/**
	 * Called when user chooses to cancel race.
	 */
	public void cancelRace(Long raceID)
	{
		racesEJB.cancelRace(getCurrentUser(), raceID);
		enteredRaceID = null;
	}
	
	/**
	 * Returns the list of all available races.
	 */
	public List<Race> getRaces()
	{
		return racesEJB.getRacesList();
	}
	
	/**
	 * Returns the remaining time in seconds before the start of a given race. 
	 */
	public int secondsToStart(Long raceID)
	{
		return racesEJB.secondsToStart(raceID);
	}
	
	/**
	 * Returns an appropriate string for display on the page. 
	 */
	public String formattedRaceTime(Long time)
	{
		long millis = time % 1000;
		long sec = (time / 1000) % 60;
		long min = (time / (1000*60)) % 60;
		long h = (time / (1000*60*60)) % 60;
		return h + "h " + min + "min " + sec + "s " + millis + "mls"; 
	}
	
	public Long getEnteredRaceID()
	{
		return this.enteredRaceID;
	}
	public Long getPreviousRaceID()
	{
		return this.previousRaceID;
	}
	
	public List<RaceResult> getPreviousRaceResults()
	{
		return statsEJB.getRaceResults(previousRaceID);
	}
	
	public int getAwardFromPreviousRace()
	{
		return statsEJB.getAwardFromRace(getCurrentUser(), previousRaceID);
	}
	
	/**
	 * Dummy List generation.
	 */
	public List getDummyArray()
	{
		List l = new ArrayList(5); //max num of players
		for (int i=0; i<5; ++i)
			l.add(1);
		return l ;
	}
}
